#ifndef PBVP_PROTEIN_RENDERER_H
#define PBVP_PROTEIN_RENDERER_H

#include <vector>

#include "../../renderer/proteinrenderplugin.h"
#include "../../shape/sphere.h"
#include "../../shape/cylinder.h"

namespace PBVP {
	class ProteinData;
	class ProteinDataNode;
	/// <summary>
	/// 
	/// </summary>
	class ProteinRenderer : public QObject, public ProteinRenderPlugin {
		Q_OBJECT
		Q_INTERFACES(PBVP::RenderPlugin)

	public:
		/// <summary>
		/// Constructor
		/// </summary>
		ProteinRenderer();
		
		/// <summary>
		/// Destructor
		/// </summary>
		~ProteinRenderer();
		
		///
		virtual QString name() const {
			return QString("Protein Renderer");
		}
		
		///
		virtual QString description() const {
			return QString("Default Protein Renderer");
		}
		
		/* RenderPlugin Specific functions */
		///
		virtual RenderPlugin* clone();
		
		/**
		 * This function sets up rendering attributes before each rendering
		 */
		virtual void begin();

		/// End the rendering of the current Renderer
		virtual void end();
		
		/// Return the control widget of the renderer
		virtual QWidget * getRenderControl() const;
		
		/**
		 * If it returns false, this plugin should not be loaded
		 */
		virtual bool initRender();
		
		/// Is given data type supported by the renderer
		virtual bool isSupported(DataInterface *pData) const;
		
		/// Rendering function
		virtual void render(DataNode *pDataNode);
		
		///
		virtual void setDataNode(DataNode *pDataNode);
		
		/// Reset all default settings
		virtual void reset();
		
		/**
		 *	call this method when the plugin is being activated,
		 *	either during startup or at any other time
		 */
		virtual void initialize(MainInterface *mainInterface);

	public slots:
		void updateView();
		///
		void setShowProtein(int state);
		///
		void setShowAtoms(int state);
		///
		void setShowBackbone(int state);
		/// 
		void setShowBBox(int state);

	protected:
		friend class ProteinRenderControl;

		ProteinRenderControl *m_pRendControl;
		bool m_ShowProtein;
		bool m_ShowAtoms;
		bool m_ShowBackbone;
		bool m_ShowRibbon;
		bool m_ShowBBox;

		ProteinDataNode *m_pProNode;
		ProteinData* m_pProtein;

	private:
		void displayChains();

		// shape varialbes used for rendering the protein
		std::vector<Sphere *> atoms;
		std::vector<Cylinder *> bonds;
	};
}

#endif